package com.unknown

import org.apache.activemq.broker.Broker
import org.apache.activemq.broker.BrokerFilter
import org.apache.activemq.broker.ConnectionContext
import org.apache.activemq.command.ConnectionInfo
import org.apache.activemq.jaas.GroupPrincipal
import org.apache.activemq.security.SecurityContext

class AuthenticationBroker extends BrokerFilter {

	public static Map activeKeys = [:]
	
	public def activeContexts = []
	
	AuthenticationBroker(Broker _next){
		super(_next)
	}
	
	SecurityContext localConnection(){
		SecurityContext s = new SecurityContext("system"){
			public Set<?> getPrincipals(){
				return [new GroupPrincipal("ROLE_ADMIN"), new GroupPrincipal("ROLE_SYSTEM")] as HashSet;
			}
		}
		return s;
	}
	
	SecurityContext sessionConnection(ConnectionContext context, ConnectionInfo info) throws SecurityException {
		def username = info.getUserName();
		def password = info.getPassword();
		println("Looking for ${username}|${password} in ${activeKeys}")
		if( !password || !activeKeys.containsKey(username) || password != activeKeys[username])
			throw new SecurityException("User name or password is invalid")
		
		SecurityContext s = new SecurityContext(info.getUserName()){
			public Set<?> getPrincipals(){
				return [new GroupPrincipal("ROLE_ADMIN")] as Set;
			}
		}
		return s;
	}
	
	void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
		if( !context.securityContext ){
			SecurityContext c = null;
			println "Connection from " + info.clientIp
			if( info.getClientIp().contains("localhost") ){
				c = localConnection()
			}else{
				c = sessionConnection(context, info);
			}
			context.securityContext = c;
			activeContexts << c;
		}
		super.addConnection(context, info);
	}
	
	void removeConnection(ConnectionContext context, ConnectionInfo info, Throwable error) throws Exception {
		super.removeConnection(context, info, error)
		if( activeContexts.remove(context.getSecurityContext()))
			context.setSecurityContext(null)
	}

}
